void *reply;
char *path, *token;
struct watch_adapter *watch, *tmp_watch;
- int err;
+ int err, rc = len;
if ((len + u->len) > sizeof(u->u.buffer))
return -EINVAL;
return -EFAULT;
u->len += len;
- if (u->len < (sizeof(u->u.msg) + u->u.msg.len))
- return len;
+ if ((u->len < sizeof(u->u.msg)) ||
+ (u->len < (sizeof(u->u.msg) + u->u.msg.len)))
+ return rc;
msg_type = u->u.msg.type;
case XS_SET_PERMS:
if (msg_type == XS_TRANSACTION_START) {
trans = kmalloc(sizeof(*trans), GFP_KERNEL);
- if (!trans)
- return -ENOMEM;
+ if (!trans) {
+ rc = -ENOMEM;
+ goto out;
+ }
}
reply = xenbus_dev_request_and_reply(&u->u.msg);
if (IS_ERR(reply)) {
kfree(trans);
- return PTR_ERR(reply);
+ rc = PTR_ERR(reply);
+ goto out;
}
if (msg_type == XS_TRANSACTION_START) {
case XS_UNWATCH:
path = u->u.buffer + sizeof(u->u.msg);
token = memchr(path, 0, u->u.msg.len);
- if (token == NULL)
- return -EILSEQ;
+ if (token == NULL) {
+ rc = -EILSEQ;
+ goto out;
+ }
token++;
if (msg_type == XS_WATCH) {
err = register_xenbus_watch(&watch->watch);
if (err) {
free_watch_adapter(watch);
- return err;
+ rc = err;
+ goto out;
}
list_add(&watch->list, &u->watches);
&u->watches, list) {
if (!strcmp(watch->token, token) &&
!strcmp(watch->watch.node, path))
- break;
{
unregister_xenbus_watch(&watch->watch);
list_del(&watch->list);
break;
default:
- return -EINVAL;
+ rc = -EINVAL;
+ break;
}
+ out:
u->len = 0;
- return len;
+ return rc;
}
static int xenbus_dev_open(struct inode *inode, struct file *filp)